import axios, {
  AxiosInstance,
  AxiosError,
  InternalAxiosRequestConfig,
  AxiosRequestConfig,
} from "axios";
import {
  showFullScreenLoading,
  tryHideFullScreenLoading,
} from "@/components/Loading/fullScreen";
import { LOGIN_URL } from "@/config";
import { ElMessage } from "element-plus";
import { ResultEnum } from "@/enums/httpEnum";
import { checkStatus } from "./helper/checkStatus";
import { AxiosCanceler } from "./helper/axiosCancel";
import { useUserStore } from "@/stores/modules/user";
import router from "@/routers";

export interface CustomAxiosRequestConfig extends InternalAxiosRequestConfig {
  loading?: boolean;
  cancel?: boolean;
}

const config = {
  // 默认地址请求地址，可在 .env.** 文件中修改
  baseURL: import.meta.env.VITE_API_URL as string,
  // 设置超时时间
  timeout: ResultEnum.TIMEOUT as number,
  // 跨域时候允许携带凭证
  withCredentials: true,
  headers: {
    // "Content-Type": "application/x-www-form-urlencoded",
    "Content-Type": "application/json",
  },
};

// interface MyAxiosRequestConfig<T = any> extends AxiosRequestConfig<T> {
//   loading?: boolean; // 自定义属性
//   cancel?:boolean
// }
export const http = axios.create(config);

//添加一个请求拦截器
http.interceptors.request.use(
  (config: any) => {
    console.log("config", config);
    const userStore = useUserStore();
    // 重复请求不需要取消，在 api 服务中通过指定的第三个参数: { cancel: false } 来控制
    config.cancel ??= true;
    config.cancel && axiosCanceler.addPending(config);
    // 当前请求不需要显示 loading，在 api 服务中通过指定的第三个参数: { loading: false } 来控制
    config.loading ??= true;
    config.loading && showFullScreenLoading();

    if (userStore.token) {
      config.headers.token = `${userStore.token}`;
    }
    // if (config.headers && typeof config.headers.set === "function") {
    //   config.headers.set("token", userStore.token);
    // }
    return config;
  },
  (error: AxiosError) => {
    return Promise.reject(error);
  }
);

http.interceptors.response.use(
  (response: any & { config: any }) => {
    const { data, config } = response;

    const userStore = useUserStore();
    axiosCanceler.removePending(config);
    config.loading && tryHideFullScreenLoading();
    // 登录失效
    if (data.code == ResultEnum.OVERDUE) {
      userStore.setToken("");
      router.replace(LOGIN_URL);
      // ElMessage.error(data.msg);
      return Promise.reject(data);
    }
    // 全局错误信息拦截（防止下载文件的时候返回数据流，没有 code 直接报错）
    if (data.code && data.code !== ResultEnum.SUCCESS) {
      // ElMessage.error(data.msg);
      return Promise.reject(data);
    }
    // 成功请求（在页面上除非特殊情况，否则不用处理失败逻辑）
    return data;
  },
  async (error: AxiosError) => {
    const { response } = error;
    tryHideFullScreenLoading();
    // 请求超时 && 网络错误单独判断，没有 response
    if (error.message.indexOf("timeout") !== -1)
      ElMessage.error("请求超时！请您稍后重试");
    if (error.message.indexOf("Network Error") !== -1)
      ElMessage.error("网络错误！请您稍后重试");
    // 根据服务器响应的错误状态码，做不同的处理
    if (response) checkStatus(response.status);
    // 服务器结果都没有返回(可能服务器错误可能客户端断网)，断网处理:可以跳转到断网页面
    if (!window.navigator.onLine) router.replace("/500");
    return Promise.reject(error);
  }
);

const axiosCanceler = new AxiosCanceler();
